/* -*- C++ -*- */

//=============================================================================
/*
* @author Feloweria <380374483@qq.com>
* Copyright (C) Feloweria
*
* $ID 2014-05-14 11:24:02 AM
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* @version 1.0
*/
//=============================================================================
#ifndef FLOWRIA_SOCKET_INCLUDE
#define FLOWRIA_SOCKET_INCLUDE

#include "Network/SocketBuffer.h"
#include "Thread/Atomic.h"

#ifdef __WINDOWS__
	#include <winsock2.h>
	#include <Windows.h>
#endif

#define SOCKET_RECV_SIZE	32 * 1024
#define SOCKET_SEND_SIZE	32 * 1024

FELOWRIA_BEGIN

#ifdef __WINDOWS__
enum SocketEvent
{
	SOCKET_EVENT_BEGIN,
	SOCKET_EVENT_READ,
	SOCKET_EVENT_WRITE,
	SOCKET_EVENT_END
};

struct OVERLAPPEDEVENT
{
	OVERLAPPED overlap;
	SocketEvent type;
	SocketBuffer *socket_buffer;
};
#endif
class SocketThread;

class DLL_EXPORT Socket
{
	
public:
	Socket();
	~Socket();
	
public:
	int64 Handle() const;
	
public:
	void OnAccept(SocketThread *thread,int64 sock,const char *ip,int32 port);

public:
	bool Create();

public:
	void Read();
	void Send();

public:
	void Reset();
	
public:
	OutputStream* GetReadStream();
	InputStream* GetWriteStream();

public:
	bool Connect(const char *addr, int32 port);
	void Disconnect();
	void Release();

public:
	virtual void OnConnect() = 0;
	virtual void OnDisconnect() = 0;
	
public:
	bool Connected() const;
	bool Disconnected() const;
protected:
	int64 sock;
	
	String ip;
	int32 port;
	
	bool connected;
	bool disconnected;

	AtomicBool send_lock;
protected:
	char recv_block[SOCKET_RECV_SIZE];
	char send_block[SOCKET_SEND_SIZE];

#ifdef __WINDOWS__
protected:
	OVERLAPPEDEVENT read_event;
	OVERLAPPEDEVENT write_event;

#endif

protected:
	SocketBuffer recv_buffer;
	SocketBuffer send_buffer;

private:
	SocketThread *thread;
};

FELOWRIA_END

#include "Socket.inl"

#endif // FLOWRIA_NETWORD_SOCKET_INCLUDE
